package com.camel.chart.utils.entity;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.camel.chart.MainApplication;
import com.camel.chart.utils.NetInterfaceUtil;
import com.camel.chart.utils.SerializeUtil;
import javafx.scene.control.ChoiceDialog;
import lombok.Data;

import java.io.Serializable;
import java.net.SocketException;
import java.util.List;
import java.util.Optional;
import java.util.Vector;

@Data
public class ApplicationConfig implements Serializable {

    private static final long serialVersionUID = 1L;

    private volatile static ApplicationConfig instance;

    private ApplicationConfig() {
    }

    public static synchronized ApplicationConfig getInstance() {
        if (instance == null) {
            synchronized (ApplicationConfig.class) {
                if (instance == null) {
                    instance = new ApplicationConfig();
                }
            }
        }
        return instance;
    }

    public static void setInstance(ApplicationConfig instance) {
        if (instance == null) {
            synchronized (ApplicationConfig.class) {
                if (instance == null) {
                    instance = new ApplicationConfig();
                }
            }
        }
    }

    // 网卡
    private ChartNetWorkInterface chartNetWorkInterface;

    // 网络设备
    public Vector<NetDevice> devices;

    public NetDevice currentDevice;

    public NetDevice MyDevice;

    public MainApplication application;

    public Vector<NetDevice> getDevices() {
        if (CollectionUtil.isEmpty(devices)) {
            setDevices(new Vector<>());
        }
        return this.devices;
    }

    public ChartNetWorkInterface getChartNetWorkInterface() {
        try {
            if (ObjectUtil.isEmpty(chartNetWorkInterface)) {
                List<ChartNetWorkInterface> choices = NetInterfaceUtil.getNetInterfaces();
                ChoiceDialog<ChartNetWorkInterface> dialog = new ChoiceDialog<>(null, choices);
                dialog.setTitle("请选择网卡");
                Optional<ChartNetWorkInterface> result = dialog.showAndWait();
                if (result.isPresent()) {
                    System.out.println("Your choice: " + result.get());
                    setChartNetWorkInterface(result.get());
                    NetDevice.myInetAddress = result.get().getInetAddress();
                    serilizeAll();
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return chartNetWorkInterface;
    }

    public void serializeDevices() {
        // 原有的
        Vector<NetDevice> netDevices = deserializeDevices();
        for (NetDevice d : ApplicationConfig.instance.getDevices()) {
            if(netDevices.contains(d)) {
                NetDevice netDevice = netDevices.get(netDevices.indexOf(d));
                netDevice.setMyDevice(d.isMyDevice());
                netDevice.setRemark(d.getRemark());
                netDevice.setName(d.getName());
            } else {
                netDevices.add(d);
            }

        }
        SerializeUtil.serializeObject(netDevices, CommonConstants.DEFAULT_CONFIG_DEVICE_SERIALIZABLE_FILE);
        System.out.println("序列化客户端对象集合到文件");
    }

    public Vector<NetDevice> deserializeDevices() {
        Vector<NetDevice> netDevices = (Vector<NetDevice>) SerializeUtil.deserializeObject(CommonConstants.DEFAULT_CONFIG_DEVICE_SERIALIZABLE_FILE);
        System.out.println("文件反序列化客户端到对象");

        if(CollectionUtil.isEmpty(netDevices)) {
            return new Vector<>();
        }
        return netDevices;
    }

    public void serilizeNetWorkInterface() {
        SerializeUtil.serializeObject(ApplicationConfig.getInstance().getChartNetWorkInterface(), CommonConstants.DEFAULT_CONFIG_NETWORK_INTERFACE_SERIALIZABLE_FILE);
    }

    public void serilizeAll() {
        serializeDevices();
        serilizeNetWorkInterface();
    }

    public void setCurrentDevice(NetDevice currentDevice) {
        this.currentDevice = currentDevice;
        for (NetDevice device : getDevices()) {
            if (device.equals(currentDevice)) {
                device.setRemark(currentDevice.getRemark());
                device.setName(currentDevice.getName());
            }
        }
        serializeDevices();
    }
}
